import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class User extends Entity implements KeyListener {

	private static final int up = 38;
	private static final int down = 40;
	private static final int left = 37;
	private static final int right = 39;
	private static final int releaseBomb = 32;

	private int currentKey = 0;
	private int spaceKey = 0;
	
	private int points = 0;
	
	private Map map;
	private Bomb bomb;
	
	private static String imagePath = "bomberman_user.png";
	
	public User(Map map){
		super(imagePath);
		this.map = map;

	}
	
	@Override
	public void draw(Graphics2D g2d) {
		if (bomb != null) {
			bomb.draw(g2d);
		}
		
		super.draw(g2d);
	}

	@Override
	public void step() {
		
		processKey();
	}
	public void processRight() {
		if ( (getY() % Entity.getEntityHeight() == 0)){
			if (map.isIndexMoveable((getX()+Entity.getEntityWidth())/Entity.getEntityWidth(), getY()/Entity.getEntityHeight()) ){
				setX(getX() + getStepX());
			}
		} 
	}

	public void processLeft() {
		if ( (getY() % Entity.getEntityHeight() == 0)){
			if (map.isIndexMoveable((getX()-getStepX())/Entity.getEntityWidth() , getY()/Entity.getEntityHeight()) ){
				setX(getX() - getStepX());
			}
		} 
	}

	public void processDown() {
		if ( (getX() % Entity.getEntityWidth() == 0)){
			if (map.isIndexMoveable(getX()/Entity.getEntityWidth(), (getY() + Entity.getEntityHeight())/Entity.getEntityHeight()) ){
				setY(getY() + getStepY());
			}
		} 
	}

	public void processUp() {
		if ( (getX() % Entity.getEntityWidth() == 0)){
			if (map.isIndexMoveable(getX()/Entity.getEntityWidth(), (getY() - getStepY())/Entity.getEntityHeight()) ){
				setY(getY() - getStepY());
			}
		} 
	}

	public void processReleaseBomb() {
		bomb =  new Bomb(this);
		int bombX;
		int bombY;
		
		if ((getX() % Entity.getEntityWidth()) > Entity.getEntityWidth()/2) {
			bombX = getX() - (getX() % Entity.getEntityWidth()) + Entity.getEntityWidth();
		} else {
			bombX = getX() - (getX() % Entity.getEntityWidth());
		}
		
		if ((getY() % Entity.getEntityHeight()) > Entity.getEntityHeight()/2) {
			bombY = getY() - (getY() % Entity.getEntityHeight()) + Entity.getEntityHeight();
		} else {
			bombY = getY() - (getY() % Entity.getEntityHeight());
		}
		
		bomb.setX(bombX);
		bomb.setY(bombY);
		
		this.map.setMoveableBlock(bombX/Entity.getEntityWidth(), 
								  bombY/Entity.getEntityHeight(), 
								  false);
	}

	@Override
	public void keyPressed(KeyEvent e) {
		
		// Check if a key is being held right now.
		if (currentKey != 0) {
			return;
		}
		
		int keyCode = e.getKeyCode(); 
		if(keyCode == up){
			currentKey = up;
		}else if(keyCode == down){
			currentKey = down;
		}else if(keyCode == left){
			currentKey = left;
		}else if(keyCode == right){
			currentKey = right;
		}else if(keyCode == releaseBomb){
			spaceKey = releaseBomb;
		}	
	}

	@Override
	public void keyReleased(KeyEvent e) {
		
		int keyCode = e.getKeyCode();
		
		if (keyCode == currentKey) {
			currentKey = 0;
		}
		
		if (keyCode == releaseBomb) {
			spaceKey = 0;
		}
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	public void removeBomb() {
		
		if (bomb == null) {
			return;
		}
		
		this.map.setMoveableBlock(bomb.getX()/Entity.getEntityWidth(),
								  bomb.getY()/Entity.getEntityHeight(),
								  true);
		
		bomb = null;
	}

	public void notifyMap(boolean changeColour, int range) {
		map.handleBombExplosion(bomb.getX(), bomb.getY(), range, changeColour);
	}
	
	private void processKey() {
		if(currentKey == up){
			processUp();
		}else if(currentKey == down){
			processDown();
		}else if(currentKey == left){
			processLeft();
		}else if(currentKey == right){
			processRight();
		}
		
		if (spaceKey == releaseBomb) {
			if (bomb == null) {
				processReleaseBomb();
			}
		}
	}
	
	public int getPoints() {
		return this.points;
	}
	
	public void setPoints(int points) {
		this.points = points;
	}
}
